package com.mingqi.hw.test1120;

import java.util.*;

/**
 * 磁盘容量排序
 * 磁盘的容量单位常用的有M，G，T这三个等级，它们之间的换算关系为1T = 1024G，1G = 1024M，现在给定n块磁盘的容量，请对它们按从小到大的顺序进行稳定排序，例如给定5块盘的容量，1T，20M，3G，10G6T，3M12G9M排序后的结果为20M，3G，3M12G9M，1T，10G6T。注意单位可以重复出现，上述3M12G9M表示的容量即为3M+12G+9M，和12M12G相等。
 * 输入描述:
 * 输入第一行包含一个整数n(2 <= n <= 100)，表示磁盘的个数，接下的n行，每行一个字符串(长度大于2，小于30)，表示磁盘的容量，由一个或多个格式为mv的子串组成，其中m表示容量大小，v表示容量单位，例如20M，1T，30G，10G6T，3M12G9M。
 * 磁盘容量m的范围为1到1024的正整数，容量单位v的范围只包含题目中提到的M，G，T三种，换算关系如题目描述。
 * 输出描述:
 * 输出n行，表示n块磁盘容量排序后的结果。
 * 示例1：
 * 输入
 * 3
 * 1G
 * 2G
 * 1024M
 * 输出
 * 1G
 * 1024M
 * 2G
 * 说明
 * 1G和1024M容量相等，稳定排序要求保留它们原来的相对位置，故1G在1024M之前
 * 示例2：
 * 输入
 * 3
 * 2G4M
 * 3M2G
 * 1T
 * 输出
 * 3M2G
 * 2G4M
 * 1T
 * 说明
 * 1T的容量大于2G4M，2G4M的容量大于3M2G
 */
import java.util.*;

/**
 * 磁盘容量排序
 * 磁盘的容量单位常用的有M，G，T这三个等级，它们之间的换算关系为1T = 1024G，1G = 1024M，现在给定n块磁盘的容量，
 * 请对它们按从小到大的顺序进行稳定排序，例如给定5块盘的容量，1T，20M，3G，10G6T，3M12G9M排序后的结果为20M，3G，3M12G9M，1T，10G6T。
 * 注意单位可以重复出现，上述3M12G9M表示的容量即为3M+12G+9M，和12M12G相等。
 * 输入描述:
 * 输入第一行包含一个整数n(2 <= n <= 100)，表示磁盘的个数，接下的n行，每行一个字符串(长度大于2，小于30)，
 * 表示磁盘的容量，由一个或多个格式为mv的子串组成，其中m表示容量大小，v表示容量单位，例如20M，1T，30G，10G6T，3M12G9M。
 * 磁盘容量m的范围为1到1024的正整数，容量单位v的范围只包含题目中提到的M，G，T三种，换算关系如题目描述。
 * 输出描述:
 * 输出n行，表示n块磁盘容量排序后的结果。
 * 示例1：
 * 输入
 * 3
 * 1G
 * 2G
 * 1024M
 * 输出
 * 1G
 * 1024M
 * 2G
 * 说明
 * 1G和1024M容量相等，稳定排序要求保留它们原来的相对位置，故1G在1024M之前
 * 示例2：
 * 输入
 * 3
 * 2G4M
 * 3M2G
 * 1T
 * 输出
 * 3M2G
 * 2G4M
 * 1T
 * 说明
 * 1T的容量大于2G4M，2G4M的容量大于3M2G
 */
public class ZT11 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        sortMGT(sc);
    }

    // 1. 磁盘容量排序（AC:100%）
    public static void sortMGT(Scanner sc) {
        String n = sc.nextLine();
        String[] strs = new String[Integer.valueOf(n)];
        for (int i = 0; i < Integer.valueOf(n); i++) {
            strs[i] = sc.nextLine();
        }
        // key：化为容量（单位：M）;value：加入顺序
        Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();

        // 记录化为对应最小单位M的容量下标
        List<Integer> numList = new ArrayList<>();
        for (String str : strs) {
            // System.out.println(str);
            Integer mSum = getMSum(str);
            List<String> list = map.get(mSum);
            if (list == null) {
                // 为空创建新数组
                list = new ArrayList<String>();
                // 记录当前换算为最小单位的M
                numList.add(mSum);
            }
            // list数组里添加对应的容量
            list.add(str);
            // 往map塞（key：最小单位对应的容量数值mSum；value：list）
            map.put(mSum, list);
        }
        // 数组进行从小到大排序
        numList.sort(null);
        for (Integer num : numList) { // 遍历numList数组（从小到大）
            List<String> list = map.get(num); // list已按照添加顺序记录，再遍历list输出即可
            for (String str : list) {
                System.out.println(str);
            }
            // System.out.println("mSum：" + num);
        }

    }

    // 把当前的容量换算为最小单位M对应的容量（如：2G1M = 1024*2 + 1 = 2049M ）
    public static Integer getMSum(String str) {
        // 遍历容量逐个字符，数字进行拼接添加记录，碰上单位就结算一次。最终转化为最小单位M对应的容量数值
        int mSum = 0;
        String numStr = "";
        for (char ch : str.toCharArray()) {
            if (ch == 'M') {
                // 碰上'M'单位了，直接转换，并把 numStr重新置空
                mSum += Integer.valueOf(numStr);
                numStr = "";
            } else if (ch == 'G') {
                // 碰上'G'单位了，转换后再乘上 1024，并把 numStr重新置空
                mSum += Integer.valueOf(numStr) * 1024;
                numStr = "";
            } else if (ch == 'T') {
                // 碰上'T'单位了，转换后再乘上 1024 * 1024，并把 numStr重新置空
                mSum += Integer.valueOf(numStr) * 1024 * 1024;
                numStr = "";
            } else {
                // 是数字，numStr进行拼接添加
                numStr += ch;
            }
        }
        // 最小单位对应的容量数值
        return mSum;
    }
}
